package com.ui;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;

import net.ledticker.LedTicker;
import net.ledticker.LedTickerFactory;

import org.swixml.SwingEngine;

import com.Ticker.elements.TextTickerElement;
import com.engine.COMMPORT;
import com.engine.IRecv;
import com.engine.ReadConfig;
import com.engine.SQEngine;
import com.engine.SaveConfig;
import com.engine.TicketEngine;
import com.engine.VideoPanel;

/*
 * This class is used to handle ticketing using socket.
 * and doing printing on ticket.
 * 
 * **/
public class TicketUI extends JFrame implements KeyListener,IRecv,ActionListener,WindowListener{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private JFrame frame;
	private JPanel media;
	private Map<String,TextTickerElement> elements = new HashMap<String,TextTickerElement>();
	private LedTicker ledTicker;
	private JPanel ticker;
	private boolean isAlive=true;
	private Dimension screen=Toolkit.getDefaultToolkit().getScreenSize();
	private TicketEngine lcdEng;
	private boolean connect_printer=false;
	private String []pakcetPrinter=new String[6];
	private String model;
	private int [] counter=new int[6];
	/** The visual component (if any) */
	Component visualComponent = null;

    /** The default control component (if any) */
	Component controlComponent = null;
	Color gridColor = new Color(0x111111);
	Color bgColor = new Color(0x333333);
	private JLabel date;
	private JButton button1,button2,button3,button4,button5,button6;
	private JLabel label1,label2,label3,label4,label5,label6;
	public static IRecv App;
	private SQEngine sqeng;
	private DecimalFormat dec = new DecimalFormat("000");
	private VideoPanel vp;
	private int numCetak=1;
	public TicketUI() throws Exception
	{
		SwingEngine  swix= new SwingEngine( this );
	    swix.render( "xml/ticketsq.xml" );
	    init();
	    frame.setUndecorated(true);
	    frame.setVisible( true );
	    frame.addKeyListener(this);
	    frame.addWindowListener(this);
	    frame.setTitle("");
	    setMaxSize();
	    createLedTickerComponent();
	    ledTicker.startAnimation();
	    ticker.add(ledTicker.getTickerComponent(),BorderLayout.CENTER);

	    //new Thread(this).start();
	    new Thread(new TimerTask()).start();
	    
	    //start to listening on socket
	    lcdEng=new TicketEngine();
	    new Thread(lcdEng).start();
	    
	    App=this;
	    //start to port serial engine..
	    sqeng=new SQEngine();
	    
	    //new DemoThread().start();
	}
	/*
	class DemoThread extends Thread
	{
		public DemoThread()
		{
			
		}
		
		public void run()
		{
			while(true)
			{
				try {
					Thread.sleep(15000L);
					Demo.showDemo();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					//e.printStackTrace();
				} catch (ClassNotFoundException e) {
					// TODO Auto-generated catch block
					//e.printStackTrace();
				} catch (InstantiationException e) {
					// TODO Auto-generated catch block
					//e.printStackTrace();
				} catch (IllegalAccessException e) {
					// TODO Auto-generated catch block
					//e.printStackTrace();
				} catch (UnsupportedLookAndFeelException e) {
					/// TODO Auto-generated catch block
					//e.printStackTrace();
				}
			}
		}
	}
	*/
	private void setMaxSize()
	{
		Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
		frame.setPreferredSize(dim);
		frame.setExtendedState(MAXIMIZED_BOTH);
	}
	
		/**
	   * Creates the LedTicker.
	   */
	  private void createLedTickerComponent() {
	    //STEP1 : create the component
	    ledTicker = LedTickerFactory.createLedTicker();
	    ledTicker.setElementGap(2);
	    ledTicker.setTokenGap(2);
	    ledTicker.setDotSize(3, 3);
	    ledTicker.setDotGaps(0, 0);
	    ledTicker.setBackgroundColor(frame.getBackground());
	    ledTicker.setDotOffColor(gridColor);
	    ledTicker.getTickerComponent().setBounds(0,screen.height,screen.width,30);
	    ledTicker.getTickerComponent().setPreferredSize(new Dimension(screen.width,30));
	    TextTickerElement ste = new TextTickerElement(ReadConfig.GET("LED_TEXT"));
	    elements.put("1",ste);
	    ledTicker.addElement(ste);
	  }
	
	JLabel logo;
	private void init()
	{
		try {
			ReadConfig.getInstance(null);
			counter[0]=Integer.parseInt(ReadConfig.GET("COUNTER1"));
			counter[1]=Integer.parseInt(ReadConfig.GET("COUNTER2"));
			counter[2]=Integer.parseInt(ReadConfig.GET("COUNTER3"));
			counter[3]=Integer.parseInt(ReadConfig.GET("COUNTER4"));
			counter[4]=Integer.parseInt(ReadConfig.GET("COUNTER5"));
			counter[5]=Integer.parseInt(ReadConfig.GET("COUNTER6"));
			
			//reading commport printer.
			COMMPORT.commport= ReadConfig.GET("COMMPORT");
			COMMPORT.baudrate=Integer.parseInt(ReadConfig.GET("BAUDRATE"));
			COMMPORT.databits=Integer.parseInt(ReadConfig.GET("DATABITS"));
			COMMPORT.stopbits=Integer.parseInt(ReadConfig.GET("STOPBITS"));
			COMMPORT.parity=Integer.parseInt(ReadConfig.GET("PARITY"));
			
			pakcetPrinter[0] = ReadConfig.GET(("PRINTER_PACKET_DATA_1"));
			pakcetPrinter[1] = ReadConfig.GET(("PRINTER_PACKET_DATA_2"));
			pakcetPrinter[2] = ReadConfig.GET(("PRINTER_PACKET_DATA_3"));
			pakcetPrinter[3] = ReadConfig.GET(("PRINTER_PACKET_DATA_4"));
			pakcetPrinter[4] = ReadConfig.GET(("PRINTER_PACKET_DATA_5"));
			pakcetPrinter[5] = ReadConfig.GET(("PRINTER_PACKET_DATA_6"));
			
			connect_printer=ReadConfig.GET(("CONNECT_PRINTER")).equals("1") ? true :false;
			model= ReadConfig.GET(("PRINTER_MODEL"));
			numCetak = Integer.parseInt(ReadConfig.GET(("NUM_CETAK")));
			label1.setHorizontalTextPosition(SwingConstants.CENTER);
			label2.setHorizontalTextPosition(SwingConstants.CENTER);
			label3.setHorizontalTextPosition(SwingConstants.CENTER);
			label4.setHorizontalTextPosition(SwingConstants.CENTER);
			label5.setHorizontalTextPosition(SwingConstants.CENTER);
			label6.setHorizontalTextPosition(SwingConstants.CENTER);
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
		} catch (IOException e) {
			// TODO Auto-generated catch block
		}
		
		
		logo.setIcon(new ImageIcon("images/logo_upper_left.png"));
		logo.setOpaque(true);
		logo.setBackground(Color.LIGHT_GRAY);
		
		showTime();
		Font f = new Font("Tahoma",Font.BOLD,20);
		date.setFont(f);
		date.setForeground(Color.RED);
		try {
			ReadConfig.getInstance(null);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//media.add(new VideoPanel("video/1.mpg"));
		SwingUtilities.invokeLater(new Runnable(){
			public void run()
			{
				String vol=ReadConfig.GET("VOLUME");
				float volume = Float.parseFloat(vol==null ? "1.0" : vol);
				vp=new VideoPanel(volume);
				int iWidth=Integer.parseInt(ReadConfig.GET("VIDEO_WIDTH"));
				int iHeight=Integer.parseInt(ReadConfig.GET("VIDEO_HEIGHT"));
				vp.setPreferredSize(new Dimension(iWidth,iHeight));
				media.add(vp);		
			}
			
		});
		
		button1.setVisible(false);
		button1.addActionListener(this);
		button2.setVisible(false);
		button2.addActionListener(this);
		button3.setVisible(false);
		button3.addActionListener(this);
		button4.setVisible(false);
		button4.addActionListener(this);
		button5.setVisible(false);
		button5.addActionListener(this);
		button6.setVisible(false);
		button6.addActionListener(this);
	}
	
	/**
	 * @param args
	 * @throws Exception 
	 */
	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		//UIManager.setLookAndFeel("com.jtattoo.plaf.graphite.GraphiteLookAndFeel");
		new TicketUI();
	}
	public void keyTyped(KeyEvent arg0) {
		// TODO Auto-generated method stub
		
	}
	public void keyPressed(KeyEvent arg0) {
		// TODO Auto-generated method stub
		
	}
	public void keyReleased(KeyEvent arg0) {
		// TODO Auto-generated method stub
		if(arg0.getKeyCode()==KeyEvent.VK_ESCAPE)
		{
			lcdEng.stopListening();
			lcdEng=null;
			isAlive=false;
			ledTicker.stopAnimation();
			frame.setVisible(false);
			frame.dispose();
			frame=null;
		}
	}
	private void showTime()
	{
		SimpleDateFormat sdf = new SimpleDateFormat("EEE dd/MM/yyyy HH:mm:ss");
		Calendar cal = Calendar.getInstance();
		int hour = cal.get(Calendar.HOUR);
		cal.set(Calendar.HOUR,hour);
		date.setText(sdf.format(cal.getTime()));
	}
	
	class TimerTask extends Thread
	{
		public TimerTask()
		{
			
		}
		
		public void run()
		{
			while(isAlive)
			{
				showTime();
				try {
					Thread.sleep(1000L);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
				}
			}
		}
	}

	public void recv(String data) {
		// TODO Auto-generated method stub
		//System.out.println("recv: " + data);
		parse(data);
	}
	
	private void parse(String parsed)
	{
		String[] arrParse = parsed.split("\\|");
		if(arrParse[0].equals("A"))
		{
			//berarti mengirimkan antrian
			receiveQueue(arrParse[1]);
		}
		else if(arrParse[0].equals("B"))
			receiveText(arrParse[1]);
		else if(arrParse[0].equals("D"))
		{
			//set queue number
			int idx =Integer.parseInt(arrParse[1]);
			int value =Integer.parseInt(arrParse[2]);
			if(idx> counter.length-1)
				return;
			counter[idx]=value;
			if(button1.isVisible())
			{
				label1.setText(dec.format(counter[0]));
			}
			if(button2.isVisible())
			{
				label2.setText(dec.format(counter[1]));
			}
			if(button3.isVisible())
				label3.setText(dec.format(counter[2]));
			if(button4.isVisible())
				label4.setText(dec.format(counter[3]));
			if(button5.isVisible())
				label5.setText(dec.format(counter[4]));
			if(button6.isVisible())
				label6.setText(dec.format(counter[5]));
			saveCounter();
		}
		else
		{
			//reset
			String reset = ReadConfig.GET("RESET");
			String[] arrReset =reset .split("\\|");
			for(int i=0; i < arrReset.length;i++)
				counter[i]=Integer.parseInt(arrReset[i]);
			
			if(button1.isVisible())
				label1.setText(dec.format(counter[0]));
			if(button2.isVisible())
				label2.setText(dec.format(counter[1]));
			if(button3.isVisible())
				label3.setText(dec.format(counter[2]));
			if(button4.isVisible())
				label4.setText(dec.format(counter[3]));
			if(button5.isVisible())
				label5.setText(dec.format(counter[4]));
			if(button6.isVisible())
				label6.setText(dec.format(counter[5]));
			saveCounter();
		}
	}
	
	private void receiveText(String text)
	{
		TextTickerElement ste = (TextTickerElement)elements.get("1");
		ste.setText(text);
		ledTicker.update(ste);
	}
	
	private void receiveQueue(String service)
	{
		if(!button1.isVisible())
		{
			button1.setVisible(true);
			button1.setText(service);
			label1.setText(dec.format(counter[0]));
			return;
		}
		if(!button2.isVisible())
		{
			button2.setVisible(true);
			button2.setText(service);
			label2.setText(dec.format(counter[1]));
			return;
		}
		if(!button3.isVisible())
		{
			button3.setVisible(true);
			button3.setText(service);
			label3.setText(dec.format(counter[2]));
			return;
		}
		if(!button4.isVisible())
		{
			button4.setVisible(true);
			button4.setText(service);
			label4.setText(dec.format(counter[3]));
			return;
		}
		if(!button5.isVisible())
		{
			button5.setVisible(true);
			button5.setText(service);
			label5.setText(dec.format(counter[4]));
			return;
		}
		if(!button6.isVisible())
		{
			button6.setVisible(true);
			button6.setText(service);
			label6.setText(dec.format(counter[5]));
			return;
		}
	}

	public void actionPerformed(ActionEvent arg0) {
		// TODO Auto-generated method stub
		if(arg0.getSource() instanceof JButton)
		{
			JButton btn = (JButton)arg0.getSource();
			String msg="";
			if(btn==button1)
			{
				counter[0]++;
				msg ="C|1" + "|" + counter[0];
				label1.setText(dec.format(counter[0]));
				for(int i=0; i <numCetak;i++)
					sqeng.send(model,btn.getText(),dec.format(counter[0]));
			}
			if(btn==button2)
			{
				counter[1]++;
				msg ="C|2"  + "|" + counter[1];
				label2.setText(dec.format(counter[1]));
				for(int i=0; i <numCetak;i++)
					sqeng.send(model,btn.getText(),dec.format(counter[1]));
			}
			if(btn==button3)
			{
				counter[2]++;
				msg ="C|3" + "|" + counter[2];
				label3.setText(dec.format(counter[2]));
				for(int i=0; i <numCetak;i++)
					sqeng.send(model,btn.getText(),dec.format(counter[2]));
			}
			if(btn==button4)
			{
				counter[3]++;
				msg ="C|4" + "|" + counter[3];
				label4.setText(dec.format(counter[3]));
				for(int i=0; i <numCetak;i++)
					sqeng.send(model,btn.getText(),dec.format(counter[3]));
			}
			if(btn==button5)
			{
				counter[4]++;
				msg ="C|5" + "|" + counter[4];
				label5.setText(dec.format(counter[4]));
				for(int i=0; i <numCetak;i++)
					sqeng.send(model,btn.getText(),dec.format(counter[4]));
			}
			if(btn==button6)
			{
				counter[5]++;
				msg ="C|6" + "|" + counter[5];
				label6.setText(dec.format(counter[5]));
				for(int i=0; i <numCetak;i++)
					sqeng.send(model,btn.getText(),dec.format(counter[5]));
			}
			//send to main queue application.
			lcdEng.sendMessage(msg);
			
			//save counter to file.
			saveCounter();
		}
	}
	
	private void saveCounter()
	{
		try {
			SaveConfig.getInstance(null);
			SaveConfig.PUT("COUNTER1",String.valueOf(counter[0]));
			SaveConfig.PUT("COUNTER2",String.valueOf(counter[1]));
			SaveConfig.PUT("COUNTER3",String.valueOf(counter[2]));
			SaveConfig.PUT("COUNTER4",String.valueOf(counter[3]));
			SaveConfig.PUT("COUNTER5",String.valueOf(counter[4]));
			SaveConfig.PUT("COUNTER6",String.valueOf(counter[5]));
			SaveConfig.Close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}

	public void send() {
		// TODO Auto-generated method stub
		String msg = "C|1|" + counter[0];
		lcdEng.sendMessage(msg);
		msg = "C|2|" + counter[1];
		lcdEng.sendMessage(msg);
		msg = "C|3|" + counter[2];
		lcdEng.sendMessage(msg);
		msg = "C|4|" + counter[3];
		lcdEng.sendMessage(msg);
		msg = "C|5|" + counter[4];
		lcdEng.sendMessage(msg);
		msg = "C|6|" + counter[5];
		lcdEng.sendMessage(msg);
	}

	public void connect() {
		// TODO Auto-generated method stub
		
	}

	public void disconnect() {
		// TODO Auto-generated method stub
		button1.setVisible(false);
		button2.setVisible(false);
		button3.setVisible(false);
		button4.setVisible(false);
		button5.setVisible(false);
		button6.setVisible(false);
		label1.setText("");
		label2.setText("");
		label3.setText("");
		label4.setText("");
		label5.setText("");
		label6.setText("");
	}

	public void windowOpened(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	public void windowClosing(WindowEvent arg0) {
		// TODO Auto-generated method stub
		if(vp!=null)
			vp.save();
	}

	public void windowClosed(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	public void windowIconified(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	public void windowDeiconified(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	public void windowActivated(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	public void windowDeactivated(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}
}
